#include "GameEvent.h"

GameEvent::GameEvent(void)
{
	type = EVENT_UNDEFINED;
	source = "UNIDENTIFIED";
	id = -1;
	code = -1;
	angle = -1;
	x_coordinate = -1;
	y_coordinate = -1;
	this->bulletMoves =new list<ByteBuffer*>;
}

GameEvent::GameEvent(EventType type, string source)
{
	this->type = type;
	this->source = source;
	id = -1;
	code = -1;
	angle = -1;
	x_coordinate = -1;
	y_coordinate = -1;
	this->bulletMoves =new list<ByteBuffer*>;
}

GameEvent::~GameEvent(void)
{
	delete this->bulletMoves;
}

EventType GameEvent::getType(void)
{
	return type;
}

EventType GameEvent::getType(int type)
{
	EventType eventType = EVENT_UNDEFINED;
	if (type == EVENT_GAME_SESSION_BEGIN)
	{
		eventType = EVENT_GAME_SESSION_BEGIN;
	}
	else if (type == EVENT_GAME_SESSION_END)
	{
		eventType = EVENT_GAME_SESSION_END;
	}
	else if (type == EVENT_GAME_SESSION_CLIENTSERVER)
	{
		eventType = EVENT_GAME_SESSION_CLIENTSERVER;
	}
	else if (type == EVENT_MOVE)
	{
		eventType = EVENT_MOVE;
	}
	return eventType;
}

void GameEvent::setName(string name)
{
	this->name = name;
}

string GameEvent::getName()
{
	return name;
}

string GameEvent::getSource(void)
{
	return source;
}

void GameEvent::setCode(int code)
{
	this->code = code;
}

int GameEvent::getCode()
{
	return code;
}

void GameEvent::setId(int id)
{
	this->id = id;
}

int GameEvent::getId()
{
	return this->id;
}

void GameEvent::setAngle(int angle)
{
	this->angle = angle;
}

int GameEvent::getAngle()
{
	return angle;
}

void GameEvent::setX(int x)
{
	x_coordinate = x;
}

int GameEvent::getX(void)
{
	return x_coordinate;
}

void GameEvent::setY(int y)
{
	y_coordinate = y;
}

int GameEvent::getY(void)
{
	return y_coordinate;
}

ByteBuffer* GameEvent::marshal(void)
{
	ByteBuffer* buffer = new ByteBuffer();
	buffer->put("|type=");
	buffer->put(type);
	buffer->put("|name=");
	buffer->put(name);
	buffer->put("|source=");
	buffer->put(source);
	buffer->put("|code=");
	buffer->put(code);
	buffer->put("|id=");
	buffer->put(id);
	buffer->put("|angle=");
	buffer->put(angle);
	buffer->put("|xpos=");
	buffer->put(x_coordinate);
	buffer->put("|ypos=");
	buffer->put(y_coordinate);
	buffer->put("|");
	if(!this->bulletMoves->empty()){
		list<ByteBuffer*>::iterator it = this->bulletMoves->begin();
		while(it != this->bulletMoves->end()){
			buffer->put((*it)->get());
			it++;
		}
	
	}

	return buffer;
}

void GameEvent::unmarshal(ByteBuffer* buffer)
{
	bool first =true;
	string temp(buffer->get());
	string temp2 = temp.substr(0, buffer->size());
	string token;
	string key;
	string value;
	size_t found;
	int index = 0;
	GameEvent* ev= new GameEvent();
	Tokenizer tokenizer(temp2, "|");
	while (tokenizer.nextToken())
	{
        token = tokenizer.getToken();
		found = token.find("=", 0);
		if (found != string::npos)
		{
			key = token.substr(0, found);
			value = token.substr(found+1, token.length()-key.length()+1);
			if(first){
			if (key == "type")
			{
				type = GameEvent::getType(atoi(value.c_str()));
			}
			else if (key == "name")
			{
				name = value;
			}
			else if (key == "source")
			{
				source = value;
			}
			else if (key == "code")
			{
				code = atoi(value.c_str());
			}
			else if (key == "id")
			{
				id = atoi(value.c_str());
			}
			else if (key == "angle")
			{
				angle = atoi(value.c_str());
			}
			else if (key == "xpos")
			{
				x_coordinate = atoi(value.c_str());
			}
			else if (key == "ypos")
			{
				y_coordinate = atoi(value.c_str());
				first=true;
			}
			}else{
				if (key == "type")
			{
				
				ev->setType(GameEvent::getType(atoi(value.c_str())));
			}
			else if (key == "name")
			{
				ev->setName( value);
			}
			else if (key == "source")
			{
				ev->setSource(value);
			}
			else if (key == "code")
			{
				ev->setCode(atoi(value.c_str()));
			}
			else if (key == "id")
			{
				ev->setId(atoi(value.c_str()));
			}
			else if (key == "angle")
			{
				ev->setAngle(atoi(value.c_str()));
			}
			else if (key == "xpos")
			{
				ev->setX( atoi(value.c_str()));
			}
			else if (key == "ypos")
			{
				ev->setY( atoi(value.c_str()));
				this->bulletMoves->push_back(ev->marshal());
			}
			
			
			
			
			
			}
		}
	}
}
list<GameEvent*>* GameEvent::unmarshalList(ByteBuffer* b){
	string temp(b->get());
	string temp2 = temp.substr(0, b->size());
	string token;
	string key;
	string value;
	size_t found;
	list<GameEvent*>* myList = new list<GameEvent*>;
	GameEvent* newEv =NULL;
	int index = 0;
	Tokenizer tokenizer(temp2, "|");
	while (tokenizer.nextToken())
	{
        token = tokenizer.getToken();
		found = token.find("=", 0);
		if (found != string::npos)
		{
			key = token.substr(0, found);
			value = token.substr(found+1, token.length()-key.length()+1);

			if (key == "type")
			{
				newEv = new GameEvent();
				newEv->setType( GameEvent::getType(atoi(value.c_str())));
			}
			else if (key == "name")
			{
				newEv->setName(value);
			}
			else if (key == "source")
			{
				newEv->setSource(value);
			}
			else if (key == "code")
			{
				newEv->setCode(atoi(value.c_str()));
			}
			else if (key == "id")
			{
				newEv->setId(atoi(value.c_str()));
			}
			else if (key == "angle")
			{
				newEv->setAngle(atoi(value.c_str()));
			}
			else if (key == "xpos")
			{
				newEv->setX(atoi(value.c_str()));
			}
			else if (key == "ypos")
			{
				newEv->setY(y_coordinate = atoi(value.c_str()));
				myList->push_back(newEv);	
			}
		}
	}
	return myList;
}

string GameEvent::toString(void)
{
	string str("");
	stringstream ss;
	ss << type;
	str.append("[").append(ss.str());
	ss.str("");
	str.append("|").append(name);
	str.append("|").append(source);
	ss << code;
	str.append("|").append(ss.str());
	ss.str("");
	ss << id;
	str.append("|").append(ss.str());
	ss.str("");
	ss << angle;
	str.append("|").append(ss.str());
	ss.str("");
	ss << x_coordinate;
	str.append("|").append(ss.str());
	ss.str("");
	ss << y_coordinate;
	str.append("|").append(ss.str());
	str.append("]");
	return str;
}

void GameEvent::setType(EventType e){
	this->type= e;
}

void GameEvent::setSource(std::string s){
	this->source = s;
}